package model

import (
	"encoding/json"
	"time"
)

type TaskOperate uint8
type TaskType uint8
type TaskStatus uint8
type TaskSubStatus uint8
type PalletDetectionType uint8
type TaskLocationType uint8
type GenerateFlag uint8
type MainTaskFlagType uint8
type CharerModeType uint8

const (
	CharerModeTypeNotCharger CharerModeType = 0 //非充电模式
	CharerModeTypeNormal     CharerModeType = 1 //普通充电
	CharerModeTypeTimerRule  CharerModeType = 2 //定时充电规则
)
const (
	LocationNormal      TaskLocationType = 0 //普通
	LocationGround      TaskLocationType = 1 //地堆库
	LocationThreeD      TaskLocationType = 2 //立库
	LocationFlat        TaskLocationType = 3 //平库
	LocationGroundFront TaskLocationType = 4 //地堆库前瞻点类型
)

const (
	GenerateNotFlag              GenerateFlag = 0 //未还未生成去前瞻点标记
	GenerateFrontPointFlag       GenerateFlag = 1 //生成去前瞻点标记
	GenerateFrontPointFinishFlag GenerateFlag = 2 //生成去前瞻点结束标记
	GenerateDependFlag           GenerateFlag = 3 //生成需要依赖标记

)
const (
	NomalMainTaskFlag                   MainTaskFlagType = 0
	GoToGroundLocationFrontMainTaskFlag MainTaskFlagType = 1
)

const (
	PalletDetectionTypeNone  PalletDetectionType = 0 //不检测
	PalletDetectionTypeFree  PalletDetectionType = 1 //空托检测
	PalletDetectionTypeFull  PalletDetectionType = 2 //满托检测
	PalletDetectionTypeCheck PalletDetectionType = 3 //检测

	TaskOperateExec        TaskOperate = 0 //继续执行
	TaskOperatePause       TaskOperate = 1 //任务暂停
	TaskOperateCancel      TaskOperate = 2 //任务取消
	TaskOperateForceFinish TaskOperate = 3 //强制完成
	TaskOperateRetry       TaskOperate = 4 //任务重发

	TaskTypeUnKnow       TaskType = 0  //未知
	TaskTypeNaviWithFork TaskType = 1  //组合任务
	TaskTypeFork         TaskType = 2  //货叉任务
	TaskTypeNavi         TaskType = 3  //行走任务
	TaskTypePick         TaskType = 4  //取货任务
	TaskTypePut          TaskType = 5  //放货任务
	TaskTypeCharge       TaskType = 6  //充电任务
	TaskTypeDisCharge    TaskType = 7  //断电任务
	TaskTypeStandBy      TaskType = 8  //待命任务
	TaskTypeDetection    TaskType = 9  //检测任务
	TaskTypeAvoid        TaskType = 10 //避让任务
	TaskTypeWeigh        TaskType = 11 //称重任务

	TaskStatusRegister     TaskStatus = 1  //已登记（接收到任务时状态）
	TaskStatusAssign       TaskStatus = 2  //已分配（子任务不可为此状态、把任务已经分配到AGV，等待任务解析）
	TaskStatusRunning      TaskStatus = 3  //执行中
	TaskStatusFinish       TaskStatus = 4  //已完成
	TaskStatusPausing      TaskStatus = 5  //暂停中
	TaskStatusPaused       TaskStatus = 6  //已暂停
	TaskStatusContinuing   TaskStatus = 7  //继续中
	TaskStatusCanceling    TaskStatus = 8  //取消中
	TaskStatusCanceled     TaskStatus = 9  //已取消
	TaskStatusInTheTransit TaskStatus = 10 //中转中
	TaskStatusInFinish     TaskStatus = 11 //完成中
	TaskStatusCharging     TaskStatus = 12 //充电中
	TaskStasusResolved     TaskStatus = 13 //已解析（子任务不可为此状态、已解析为子任务，等待执行）
	TaskStasusAvoid        TaskStatus = 14 //避让中
	TaskStatusError        TaskStatus = 16 //错误

	InitState            TaskSubStatus = 1  //初始状态
	WalkToTarget         TaskSubStatus = 2  //前往目标点
	WalkToTemp           TaskSubStatus = 3  //前往中转点
	WalkToTargetReplace  TaskSubStatus = 4  //前往目标避让点
	WalkToTempReplace    TaskSubStatus = 5  //前往中转避让点
	WalkTaskClearing     TaskSubStatus = 6  //避让清除中
	WalkTaskCleared      TaskSubStatus = 7  //清除完成
	WalkForwardAvoid     TaskSubStatus = 8  //前进避让
	WalkBackforwardAvoid TaskSubStatus = 9  //后退避让
	WalkNearAvoid        TaskSubStatus = 10 //就近避让
	WalkAvoidFinish      TaskSubStatus = 11 //避让完成
	WalkTempFinish       TaskSubStatus = 12 //中转点，目标避让点，中转避让点完成
)

//IsExecuting 任务执行中
func (s TaskStatus) IsExecuting() bool {
	return s == TaskStatusRunning || s == TaskStatusPausing || s == TaskStatusContinuing || s == TaskStatusInTheTransit ||
		s == TaskStatusInFinish || s == TaskStatusCharging || s == TaskStatusCanceling || s == TaskStasusAvoid
}

//IsRunning 任务运行中
func (s TaskStatus) IsRunning() bool {
	return s == TaskStatusRunning || s == TaskStatusPaused || s == TaskStatusPausing || s == TaskStatusContinuing || s == TaskStasusAvoid ||
		s == TaskStatusCanceling || s == TaskStatusInTheTransit || s == TaskStatusInFinish || s == TaskStatusCharging || s == TaskStatusError
}

// 运行中任务状态(可用于自动重发的任务)
func (s TaskStatus) IsTaskRunningTaskForAutoRetryStatus() bool {
	return s == TaskStatusRunning || s == TaskStatusContinuing || s == TaskStatusInTheTransit || s == TaskStasusAvoid
}

//暂停的任务
func (s TaskStatus) IsPause() bool {
	return s == TaskStatusPaused || s == TaskStatusPausing
}

//IsDone 任务已完成
func (s TaskStatus) IsDone() bool {
	return s == TaskStatusFinish || s == TaskStatusCanceled
}

//IsDone 任务异常
func (s TaskStatus) IsError() bool {
	return s == TaskStatusCanceling || s == TaskStatusCanceled
}

//获取未执行任务状态(已登记、已分配、已解析)
func TaskWaitingStatus() []TaskStatus {
	return []TaskStatus{TaskStatusRegister, TaskStatusAssign, TaskStasusResolved}
}

//获取任务分配的任务状态
func TaskAssignStatus() []TaskStatus {
	return []TaskStatus{
		TaskStatusRegister,
		TaskStatusAssign,
		TaskStasusResolved,
		TaskStatusRunning,
		TaskStatusPaused,
		TaskStatusPausing,
		TaskStatusContinuing,
		TaskStatusCanceling,
		TaskStatusInTheTransit,
		TaskStasusAvoid,
		TaskStatusInFinish,
		TaskStatusCharging}
}

//获取运行中任务状态
func TaskRunningStatus() []TaskStatus {
	return []TaskStatus{
		TaskStatusRunning,
		TaskStatusPaused,
		TaskStatusPausing,
		TaskStatusContinuing,
		TaskStatusCanceling,
		TaskStatusInTheTransit,
		TaskStasusAvoid,
		TaskStatusInFinish,
		TaskStatusCharging,
		TaskStatusError,
	}
}

//生成待命任务排除状态
func TaskRunStatus() []TaskStatus {
	return []TaskStatus{
		TaskStatusRunning,
		TaskStasusResolved,
		TaskStatusPaused,
		TaskStatusPausing,
		TaskStatusContinuing,
		TaskStatusCanceling,
		TaskStatusInTheTransit,
		TaskStasusAvoid,
		TaskStatusInFinish,
		TaskStatusCharging,
	}
}

//获取完成中和取消中
func TaskCancelingOrInfinshStatus() []TaskStatus {
	return []TaskStatus{
		TaskStatusCanceling,
		TaskStatusInFinish,
	}
}

func TaskFinishedStatus() []TaskStatus {
	return []TaskStatus{
		TaskStatusCanceled,
		TaskStatusFinish,
	}
}

//获取运行中任务状态(可用于自动重发的任务)
func TaskRunningTaskForAutoRetryStatus() []TaskStatus {
	return []TaskStatus{
		TaskStatusRunning,
		TaskStatusContinuing,
		TaskStatusInTheTransit,
		TaskStasusAvoid,
	}
}

//获取非中转的运行中任务状态
func TaskRunningStatusWithoutTransit() []TaskStatus {
	return []TaskStatus{
		TaskStatusRunning,
		TaskStatusPaused,
		TaskStatusPausing,
		TaskStatusContinuing,
		TaskStatusCanceling,
		TaskStatusInFinish,
		TaskStatusCharging,
		TaskStasusAvoid,
	}
}

type CompleteType uint8

const (
	CompleteTypeNomal   CompleteType = 0 //正常完成
	CompleteTypeAbnomal CompleteType = 1 //异常完成
)

type Task struct {
	//Type             TaskType   `json:"task_type" bson:"type" binding:"required,oneof=1 2 3 4 5 8"` //任务类型
	Id                     uint64              `json:"task_id" bson:"id"`                                          //主键
	Type                   TaskType            `json:"task_type" bson:"type" binding:"required"`                   //任务类型
	ExternalTaskCode       string              `json:"external_task_code" bson:"external_task_code"`               //外部任务编号
	MainTaskCode           string              `json:"main_task_code" bson:"main_task_code"`                       //主任务编号（流程任务编号）
	MapName                string              `json:"map_name" bson:"map_name"  binding:"required"`               //主任务编号（流程任务编号）
	Status                 TaskStatus          `json:"status" bson:"status"`                                       //任务状态
	AgvId                  string              `json:"agv_id" bson:"agv_id"`                                       //小车编号
	TargetSiteID           string              `json:"target_site_id" bson:"target_site_id" binding:"required"`    //目标点点位ID
	TargetLayer            int32               `json:"target_layer" bson:"target_layer"`                           //目标点点位层级
	TargetDirection        int32               `json:"target_direction" bson:"target_direction"`                   //货叉方向  0=中间、1=左、2=右、3=左2、4=右2
	Grade                  int                 `json:"grade" bson:"grade" binding:"required"`                      //任务优先级
	PalletDetection        PalletDetectionType `json:"pallet_detection" bson:"pallet_detection"`                   //货物检测：0=不检测、1=空托检测、2=满托检测
	AdditiveInfo           string              `json:"additive_info" bson:"additive_info"`                         //附加信息
	CreatedTime            time.Time           `json:"-" bson:"created_time"`                                      //创建时间
	StartTime              time.Time           `json:"-" bson:"start_time"`                                        //开始时间
	FinishTime             time.Time           `json:"-" bson:"finish_time"`                                       //结束时间
	Report                 int                 `json:"report" bson:"report"`                                       //是否上报给中间件任务完成（中间件未找到任务，回复成功） 0=未上报、1=已上报
	RetryCnt               int                 `json:"-" bson:"retry_cnt"`                                         //重新计算次数
	TargetFrontSiteId      string              `json:"-" bson:"target_front_site_id"`                              //目标点前一个点的点位编号
	AvoidAgv               string              `json:"-" bson:"avoid_agv"`                                         //
	TargetWeightMapName    string              `json:"target_weight_map_name" bson:"target_weight_map_name"`       //指定称重地图
	TargetWeightSiteID     string              `json:"target_weight_site_id" bson:"target_weight_site_id"`         //可指定的称重目标点
	GroupList              []string            `json:"group_list" bson:"group_list"`                               //地堆库组
	DependExternalTaskCode string              `json:"depend_external_task_code" bson:"depend_external_task_code"` //依赖外部任务编号

	ChargerMode   CharerModeType `json:"charger_mode" bson:"charger_mode"`       //充电模式 0:非充电 1:普通充电模式 2:定时规则充电模式
	ChargerRuleId uint16         `json:"charger_rule_id" bson:"charger_rule_id"` //当前充电的规则编号
	ChargerRule   ChargeRule     `json:"charger_rule" bson:"charger_rule"`       //当前规则

	LocationType         TaskLocationType `json:"-" bson:"location_type"`             //Enum:1:地堆库 2.立体库3.平库
	LocationGroup        string           `json:"-" bson:"location_group"`            //库位组编号
	DependTaskCodes      []uint64         `json:"-" bson:"depend_task_codes"`         //依赖任务编号集合
	GenerateFlag         GenerateFlag     `json:"-" bson:"generate_flag"`             //地堆库取货标记 0:未生成去前瞻点 1:生成去地堆库前瞻点标记  2.生成去地堆库前瞻点结束标记 3：需要依赖标记
	NotForceCompleteFlag bool             `json:"-" bson:"not_force_complete_flag"`   //不允许强制完成标记 true:不允许强制完成 false:允许强制完成
	TargetID             string           `json:"target_id" bson:"target_id"`         //最终放货到达的实际目标点点位ID
	IsOrderly            int              `json:"is_orderly" bson:"is_orderly"`       //中间件下发的任务是否有序 0 有序 1无序，可换任务 2无序，不可换任务，更新目标点
	CompleteType         CompleteType     `json:"complete_type" bson:"complete_type"` //操作指令:0=正常完成 1=异常完成
}

func (Task) TableName() string {
	return "t_data_tasks"
}

func (taskType TaskType) GetWalkType() int32 {
	if taskType == TaskTypePick {
		return 2
	} else if taskType == TaskTypePut {
		return 1
	}
	return 0
}

//判断任务是否在任务集合中
func (t Task) In(tasks []*Task) bool {
	if tasks == nil || len(tasks) < 1 {
		return false
	}
	for _, task := range tasks {
		if t.Id == task.Id {
			return true
		}
	}
	return false
}

func (t *Task) MarshalJSON() ([]byte, error) {
	type TmpJSON Task
	return json.Marshal(&struct {
		*TmpJSON
		CreatedTime DateTime `json:"created_time"`
		StartTime   DateTime `json:"start_time"`
		FinishTime  DateTime `json:"finish_time"`
	}{
		TmpJSON:     (*TmpJSON)(t),
		CreatedTime: DateTime(t.CreatedTime),
		StartTime:   DateTime(t.StartTime),
		FinishTime:  DateTime(t.FinishTime),
	})
}

type MainTask struct {
	MainTaskCode string           `json:"main_task_code" bson:"main_task_code"` //主任务编号（流程任务编号）
	TaskId       uint64           `json:"task_id" bson:"task_id"`               //任务Id
	AgvId        string           `json:"agv_id" bson:"agv_id"`                 //小车编号
	GroundId     string           `json:"ground_id" bson:"ground_id"`           //地堆库组编号
	MapName      string           `json:"map_name" bson:"map_name"`             //地图名称
	FlagType     MainTaskFlagType `json:"flag_type" bson:"flag_type"`           //1:去地堆库前瞻点标记 0：正常绑定标记
}

func (MainTask) TableName() string {
	return "t_data_main_tasks"
}
